home *** CD-ROM | disk | FTP | other *** search
/ Power Programmierung 2 / Power-Programmierung CD 2 (Tewi)(1994).iso / c / library / dos / diverses / leda / src / plane / _voronoi.c < prev    next >
Encoding:
C/C++ Source or Header  |  1991-11-15  |  2.2 KB  |  124 lines

  1. /*******************************************************************************
  2. +
  3. +  LEDA  2.1.1                                                 11-15-1991
  4. +
  5. +
  6. +  _voronoi.c
  7. +
  8. +
  9. +  Copyright (c) 1991  by  Max-Planck-Institut fuer Informatik
  10. +  Im Stadtwald, 6600 Saarbruecken, FRG     
  11. +  All rights reserved.
  12. *******************************************************************************/
  13.  
  14.  
  15. #include <LEDA/plane.h>
  16. #include <LEDA/plane_alg.h>
  17. #include <LEDA/delaunay_tree.h>
  18. #include <LEDA/d_array.h>
  19.  
  20.  
  21. declare2(d_array,point,node)
  22.  
  23. static d_array(point,node) V(nil);
  24.  
  25. static GRAPH(point,point)* G;
  26.  
  27. static double infi_length;
  28.  
  29. static point X;
  30.  
  31.  
  32. static void trace_segment(double x1, double y1, double x2, double y2, 
  33.                    double sx0, double sy0)
  34. {
  35.   point p(x1,y1);
  36.   point q(x2,y2);
  37.   point s(sx0,sy0);
  38.  
  39.   node v,w;
  40.  
  41.   if ((v = V[p]) == nil) V[p] = v = G->new_node(p);
  42.     
  43.   if ((w = V[q]) == nil) V[q] = w = G->new_node(q);
  44.  
  45.   G->new_edge(v,w,s);
  46.  
  47.  
  48. }
  49.  
  50.  
  51. static void infi_point(double x1, double y1, double x2, double y2, double* x, double* y)
  52. {
  53.   vector v(x2,y2);
  54.  
  55.   v = v.norm();
  56.  
  57.   *x = x1 + infi_length * v[0];
  58.   *y = y1 + infi_length * v[1];
  59.  
  60. }
  61.  
  62.  
  63. static int cmp_infi_pts(point& p, point& q)
  64. { // used to sort infi points clockwise around X
  65.   segment  s1(X,p);
  66.   segment  s2(X,q);
  67.   real a1 = s1.angle();
  68.   real a2 = s2.angle();
  69.   return compare(a2,a1); 
  70. }
  71.  
  72.  
  73. void VORONOI(list(point)& site_list, double R, GRAPH(point,point)& VD)
  74.    if (site_list.empty()) return;
  75.  
  76.    X = site_list.head();
  77.  
  78.    delaunay_tree DT;
  79.  
  80.    point p,q;
  81.    node v;
  82.  
  83.    list(point) infi_list;
  84.  
  85.    forall(p,site_list) DT.insert(p,0);
  86.  
  87.    infi_length = R;
  88.  
  89.    G = &VD;
  90.  
  91.    DT.trace_voronoi_edges(trace_segment, infi_point, 1);
  92.  
  93.  
  94.    // sort & link infinite points
  95.  
  96.    forall_nodes(v,VD) 
  97.      if (VD.outdeg(v) == 1) infi_list.append(VD[v]);
  98.  
  99.    infi_list.sort(cmp_infi_pts);
  100.  
  101.    point INFI(MAXDOUBLE,MAXDOUBLE);  
  102.  
  103.    list_item it;
  104.  
  105.    forall_items(it,infi_list)
  106.    {  node p = V[infi_list[it]];
  107.       node q = V[infi_list[infi_list.cyclic_succ(it)]];
  108.       point s = VD[VD.first_adj_edge(q)];
  109.       VD.new_edge(p,q,s); 
  110.     }
  111.  
  112.    forall_items(it,infi_list)
  113.    {  node p = V[infi_list[it]];
  114.       node q = V[infi_list[infi_list.cyclic_pred(it)]];
  115.       VD.new_edge(p,q,INFI);  
  116.     }
  117.  
  118.    V.clear();
  119.  
  120. }
  121.  
  122.